<?php

namespace App\Models;

use Exception;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;

class Permission extends BaseModel
{
    use HasFactory;

    const CREATED_AT = 'create_time';
    const UPDATED_AT = 'change_time';

    protected $table = 'permission';

    public function getTable()
    {
        return $this->table;
    }

    /**
     * 获取用户权限树形列表
     * @param type 0 或空获取全部数据  1 获取一级菜单  2 获取一级菜单下的所有子菜单  3 获取全部数据，但是只返回 id 和 权限名称（主要用于筛选）
     *  @param pid 当type 为 2时，必填  一级菜单的id
     */
    public function gerPermissionList($manage_id, $type = 0, $pid = null)
    {
        if ($type == 2 && empty($pid)) {
            return [];
        }

        if ($type != 2) {
            $pid = '';
        } //防止后面的数据多出

        // $cache_key = $manage_id.$type.$pid;
        // $data = Cache::get($cache_key);
        // if($data){
        //     return $data;
        // }

        $permission_id = $this->getUserPermissionId($manage_id);

        if ($type == 3) {
            $field = ['id', 'permission_name', 'pid', 'path', 'level'];
        } else {
            $field = ['id', 'icon', 'path', 'permission_name', 'order', 'pid', 'type', 'route_path', 'is_admin', 'route_name', 'level', 'path_name', 'meta_title', 'view_name'];
        }
        //   DB::enableQueryLog();
        //$permission_list = $this->select('id','path',DB::raw("CONCAT_WS('|',`permission_name`,`order`) as permission_name"),'pid','type','view_name','redirect','is_admin','route_name','level')
        $permission_list = $this->select($field)
            ->where(function ($query) use ($type, $pid) {
                if ($type == 1) {
                    $query->where('level', 1);
                } elseif ($type == 2) {
                    $pid = sprintf('%04s', $pid);
                    $query->where('path', 'like', $pid . '%')->where('level', '>', 1);
                }
            })
            ->whereIn('id', $permission_id)
            ->where('is_del', '1')
            //  ->orderBy('path')
            ->orderBy('level')
            ->orderBy('order')
            ->get()
            ->toArray();

        //  dump($permission_id);
        //  dump($permission_list);
        //  die;
        // dd(DB::getQueryLog());
        if (empty($permission_list)) {
            return [];
        }

        $res = [];
        foreach ($permission_list as $key => $value) {
            if (!$value['pid'] || (!empty($pid) && $value['level'] == 2)) {
                $res[] = $this->getTree($value, $permission_list);
            }
        }

        // Cache::put($cache_key , $res , 60);//60分钟

        return $res;
    }

    /**
     * 获取管理员所有的权限id
     */
    public function getUserPermissionId($manage_id)
    {
        if ($manage_id == 1) {
            $permission_ids = $this->where('is_del', 1)->pluck('id')->toArray();
        } else {
            $manageRoleModelObj = new ManageRole();
            $rolePermissionModelObj = new RolePermission();
            $roles = $manageRoleModelObj->getManageRole($manage_id);  //获取管理员角色
            $role_ids = array_column($roles, 'id');
            $permissions = $rolePermissionModelObj->getRolePermission($role_ids);
            $permission_ids = array_column($permissions, 'id');
        }
        return $permission_ids;
    }


    /**
     * 递归 获取权限
     **/
    function getTree($arr, $menu)
    {
        if (!$arr['pid']) {
            $arr['children'] = [];
        }

        foreach ($menu as $key => $value) {
            if ($arr['id'] == $value['pid']) {
                $temp = [];
                $temp = $this->getTree($value, $menu);
                if ($temp) {
                    $arr['children'][] = $temp;
                }
                // break;
            }
        }
        return $arr;
    }


    /*获取父级权限*/
    public function getParent()
    {
        if ($this->pid) {
            return $this->where('id', $this->pid)->first();
        } else {
            return null;
        }
    }


    /**
     *  权限添加
     * @param $data 添加的数据
     */
    public function add($data, $field = [])
    {
        $api_paths = '';
        if ($data->api_path) {
            $api_path = $data->api_path;
            $api_path = str_replace(['，', '|'], ',', $api_path);
            $api_path = explode(',', $api_path);
            foreach ($api_path as $key => $val) {
                $news_api_path = substr($val, 0, 1) == '/' ? substr($val, 1, strlen($val)) : $val;
                $api_paths .= ',' . $news_api_path;
            }
            $api_paths = trim($api_paths, ',');
        }
        $this->pid = $data->pid ? $data->pid : 0;
        $this->meta_title = $data->meta_title;
        $this->permission_name = $data->permission_name;
        //  $this->sidebar_name = $data->sidebar_name;
        $this->icon = $data->icon;
        $this->route_name = $data->route_name;
        $this->route_path = $data->route_path;
        $this->component_path = $data->component_path;
        $this->type = $data->type;
        $this->api_path = $api_paths;
        $this->view_name = $data->view_name;
        // $this->redirect = $data->redirect;
        // $this->hl_routes = $data->hl_routes;
        $this->is_admin = $data->is_admin ? $data->is_admin : 2;

        $this->save();

        /**附加上路径信息 */
        $path_names = $data->meta_title ? $data->meta_title : $data->permission_name;
        if (empty($data->pid)) {
            $this->path_name = $path_names;
            $this->path = sprintf('%04s', $this->id);
            $this->level = 1;
        } else {
            $parent = $this->find($data->pid);
            $this->path_name = $parent->path_name . '-' . $path_names;
            $this->path = $parent->path . '-' .  sprintf('%04s', $this->id);
            $this->level = count(explode('-', $parent->path)) + 1;
        }

        /**未指定order改为数字最大的一个，指定order，所有大于当前order的数自增一，其余不变 */
        $max_order = $this->where('level', 1)->max('order');
        if ($data->order) {
            if ($max_order >= $data->order) {
                $this->where('order', '>=', $data->order)->increment('order'); //所有大于当前order都减少
            }
            $this->order = $data->order;
        } else {
            $this->order =  $max_order + 1; //未指定排在最后
        }

        $this->save();
    }


    /**
     *  修改管理员
     * @param $data 添加的数据
     */
    public function change($data, $field = [], $findWhere = [])
    {
        $api_paths = '';
        if ($data->api_path) {
            $api_path = $data->api_path;
            $api_path = str_replace(['，', '|'], ',', $api_path);
            $api_path = explode(',', $api_path);
            foreach ($api_path as $key => $val) {
                $news_api_path = substr($val, 0, 1) == '/' ? substr($val, 1, strlen($val)) : $val;
                $api_paths .= ',' . $news_api_path;
            }
            $api_paths = trim($api_paths, ',');
        }
        $res = $this->where('is_del', 1)->find($data['id']);
        if (!$res) {
            return false;
        }
        $res->pid = $data->pid;
        $res->meta_title = $data->meta_title;
        $res->permission_name = $data->permission_name;
        // $res->sidebar_name = $data->sidebar_name;
        $res->icon = $data->icon;
        $res->route_name = $data->route_name;
        $res->route_path = $data->route_path;
        $res->component_path = $data->component_path;
        $res->type = $data->type;
        $res->api_path = $api_paths;
        $res->view_name = $data->view_name;
        //  $res->redirect = $data->redirect;
        //  $res->hl_routes = $data->hl_routes;
        $res->is_admin = $data->is_admin ? $data->is_admin : 2;

        /**附加上路径信息 */
        $path_names = $data->meta_title ? $data->meta_title : $data->permission_name;
        if (empty($data->pid)) {
            $res->path_name = $path_names;
            $res->path = sprintf('%04s', $data->id);
            $res->level = 1;
        } else {
            $parent = $this->find($data->pid);
            $res->path_name = $parent->path_name . '-' . $path_names;
            $res->path = $parent->path . '-' .  sprintf('%04s', $data->id);
            $res->level = count(explode('-', $parent->path)) + 1;
        }

        /**未指定order改为数字最大的一个，指定order，所有大于当前order的数自增一，其余不变 ，未指定位置不变*/
        if ($data->order) {
            $max_order = $this->where('level', 1)->max('order');
            if ($max_order >= $data->order) {
                $this->where('order', '>=', $data->order)->increment('order'); //所有大于当前order都减少
            }
            $res->order = $data->order;
        } //未指定位置不变

        $res->save();
    }


    /**
     * 判断权限是否已经存在
     * @param permission_name 权限名称
     * @param id 权限id   可选，主要是用于修改
     */
    public function permissionIsExists($permission_name, $id = null)
    {
        $res = $this->where('permission_name', $permission_name)->where(function ($query) use ($id) {
            if (!empty($id)) {
                $query->where('id', '<>', $id);
            }
        })->where('is_del', 1)->first();
        return $res;
    }

    /**
     * 判断当前权限，是否存在子集
     * @param id 权限id
     */
    public function permissionIsExistsChild($id)
    {
        $res = $this->select('id')->where('pid', $id)->where('is_del', 1)->first();
        return $res;
    }
}
